import * as cc from 'cc';
const { ccclass, property, executionOrder } = cc._decorator;

@ccclass('FixedUpdate')
@executionOrder(-100)
export class FixedUpdate extends cc.Component {
    static EventFixedUpdate = 'fixed-update';

    private static _instance: FixedUpdate = null!;
    static get instance() {
        return this._instance;
    }

    @property
    public fixedFPS = 50;

    @property
    maxStep = 5;

    private _fixedDelta = 0;
    public get fixedDelta() {
        return this._fixedDelta;
    }

    private _frameIndex = 0;
    public get frameIndex() {
        return this._frameIndex;
    }

    private accumulator = 0;

    addEvent(fn: (index: number) => void, bind: unknown) {
        this.node.on(FixedUpdate.EventFixedUpdate, fn, bind);
    }

    removeEvent(fn: (index: number) => void, bind: unknown) {
        this.node.off(FixedUpdate.EventFixedUpdate, fn, bind);
    }

    onLoad() {
        if (FixedUpdate._instance) {
            cc.error('重复注册组件');
        }
        this._fixedDelta = 1 / this.fixedFPS;
        FixedUpdate._instance = this;
    }

    update(dt: number) {
        this.accumulator += dt;

        let step = 0;
        while (
            this.accumulator >= this._fixedDelta &&
            step < this.maxStep
        ) {
            this.node.emit(
                FixedUpdate.EventFixedUpdate,
                this._frameIndex++,
            );
            this.accumulator -= this._fixedDelta;
            step++;
        }
    }
}
